import {ApolloError} from 'apollo-server-errors';

export type Nullable<T> = {
  [P in keyof T]: T[P] | null;
};

export interface GRPCPlugin {
  onCall?: (args: {requestName: string}) => void;
  onCompleted?: (args: {requestName: string}) => void;
  onError?: (args: {error: unknown; requestName: string}) => void;
}

const NOT_FOUND_ERROR_CODE = 'NOT_FOUND';
export class NotFoundError extends ApolloError {
  constructor(message: string) {
    super(message, NOT_FOUND_ERROR_CODE);

    // Note: We must redefine this property, as ApolloError's
    // "name" attribute is read-only by default
    Object.defineProperty(this, 'name', {value: 'NotFoundError'});
  }
}

// Types ported from GQL

export enum EnterpriseState {
  ACTIVE = 'ACTIVE',
  EXPIRED = 'EXPIRED',
  HEARTBEAT_FAILED = 'HEARTBEAT_FAILED',
  NONE = 'NONE',
}

export enum ResourceType {
  CLUSTER = 'CLUSTER',
  PROJECT = 'PROJECT',
  REPO = 'REPO',
  RESOURCE_TYPE_UNKNOWN = 'RESOURCE_TYPE_UNKNOWN',
  SPEC_REPO = 'SPEC_REPO',
}

export enum Permission {
  CLUSTER_AUTH_ACTIVATE = 'CLUSTER_AUTH_ACTIVATE',
  CLUSTER_AUTH_DEACTIVATE = 'CLUSTER_AUTH_DEACTIVATE',
  CLUSTER_AUTH_DELETE_EXPIRED_TOKENS = 'CLUSTER_AUTH_DELETE_EXPIRED_TOKENS',
  CLUSTER_AUTH_EXTRACT_TOKENS = 'CLUSTER_AUTH_EXTRACT_TOKENS',
  CLUSTER_AUTH_GET_CONFIG = 'CLUSTER_AUTH_GET_CONFIG',
  CLUSTER_AUTH_GET_GROUPS = 'CLUSTER_AUTH_GET_GROUPS',
  CLUSTER_AUTH_GET_GROUP_USERS = 'CLUSTER_AUTH_GET_GROUP_USERS',
  CLUSTER_AUTH_GET_PERMISSIONS_FOR_PRINCIPAL = 'CLUSTER_AUTH_GET_PERMISSIONS_FOR_PRINCIPAL',
  CLUSTER_AUTH_GET_ROBOT_TOKEN = 'CLUSTER_AUTH_GET_ROBOT_TOKEN',
  CLUSTER_AUTH_MODIFY_GROUP_MEMBERS = 'CLUSTER_AUTH_MODIFY_GROUP_MEMBERS',
  CLUSTER_AUTH_RESTORE_TOKEN = 'CLUSTER_AUTH_RESTORE_TOKEN',
  CLUSTER_AUTH_REVOKE_USER_TOKENS = 'CLUSTER_AUTH_REVOKE_USER_TOKENS',
  CLUSTER_AUTH_ROTATE_ROOT_TOKEN = 'CLUSTER_AUTH_ROTATE_ROOT_TOKEN',
  CLUSTER_AUTH_SET_CONFIG = 'CLUSTER_AUTH_SET_CONFIG',
  CLUSTER_CREATE_SECRET = 'CLUSTER_CREATE_SECRET',
  CLUSTER_DEBUG_DUMP = 'CLUSTER_DEBUG_DUMP',
  CLUSTER_DELETE_ALL = 'CLUSTER_DELETE_ALL',
  CLUSTER_ENTERPRISE_ACTIVATE = 'CLUSTER_ENTERPRISE_ACTIVATE',
  CLUSTER_ENTERPRISE_DEACTIVATE = 'CLUSTER_ENTERPRISE_DEACTIVATE',
  CLUSTER_ENTERPRISE_GET_CODE = 'CLUSTER_ENTERPRISE_GET_CODE',
  CLUSTER_ENTERPRISE_HEARTBEAT = 'CLUSTER_ENTERPRISE_HEARTBEAT',
  CLUSTER_ENTERPRISE_PAUSE = 'CLUSTER_ENTERPRISE_PAUSE',
  CLUSTER_GET_BINDINGS = 'CLUSTER_GET_BINDINGS',
  CLUSTER_GET_LOKI_LOGS = 'CLUSTER_GET_LOKI_LOGS',
  CLUSTER_GET_PACHD_LOGS = 'CLUSTER_GET_PACHD_LOGS',
  CLUSTER_IDENTITY_CREATE_IDP = 'CLUSTER_IDENTITY_CREATE_IDP',
  CLUSTER_IDENTITY_CREATE_OIDC_CLIENT = 'CLUSTER_IDENTITY_CREATE_OIDC_CLIENT',
  CLUSTER_IDENTITY_DELETE_IDP = 'CLUSTER_IDENTITY_DELETE_IDP',
  CLUSTER_IDENTITY_DELETE_OIDC_CLIENT = 'CLUSTER_IDENTITY_DELETE_OIDC_CLIENT',
  CLUSTER_IDENTITY_GET_CONFIG = 'CLUSTER_IDENTITY_GET_CONFIG',
  CLUSTER_IDENTITY_GET_IDP = 'CLUSTER_IDENTITY_GET_IDP',
  CLUSTER_IDENTITY_GET_OIDC_CLIENT = 'CLUSTER_IDENTITY_GET_OIDC_CLIENT',
  CLUSTER_IDENTITY_LIST_IDPS = 'CLUSTER_IDENTITY_LIST_IDPS',
  CLUSTER_IDENTITY_LIST_OIDC_CLIENTS = 'CLUSTER_IDENTITY_LIST_OIDC_CLIENTS',
  CLUSTER_IDENTITY_SET_CONFIG = 'CLUSTER_IDENTITY_SET_CONFIG',
  CLUSTER_IDENTITY_UPDATE_IDP = 'CLUSTER_IDENTITY_UPDATE_IDP',
  CLUSTER_IDENTITY_UPDATE_OIDC_CLIENT = 'CLUSTER_IDENTITY_UPDATE_OIDC_CLIENT',
  CLUSTER_LICENSE_ACTIVATE = 'CLUSTER_LICENSE_ACTIVATE',
  CLUSTER_LICENSE_ADD_CLUSTER = 'CLUSTER_LICENSE_ADD_CLUSTER',
  CLUSTER_LICENSE_DELETE_CLUSTER = 'CLUSTER_LICENSE_DELETE_CLUSTER',
  CLUSTER_LICENSE_GET_CODE = 'CLUSTER_LICENSE_GET_CODE',
  CLUSTER_LICENSE_LIST_CLUSTERS = 'CLUSTER_LICENSE_LIST_CLUSTERS',
  CLUSTER_LICENSE_UPDATE_CLUSTER = 'CLUSTER_LICENSE_UPDATE_CLUSTER',
  CLUSTER_LIST_SECRETS = 'CLUSTER_LIST_SECRETS',
  CLUSTER_MODIFY_BINDINGS = 'CLUSTER_MODIFY_BINDINGS',
  CLUSTER_SET_DEFAULTS = 'CLUSTER_SET_DEFAULTS',
  PERMISSION_UNKNOWN = 'PERMISSION_UNKNOWN',
  PIPELINE_LIST_JOB = 'PIPELINE_LIST_JOB',
  PROJECT_CREATE = 'PROJECT_CREATE',
  PROJECT_CREATE_REPO = 'PROJECT_CREATE_REPO',
  PROJECT_DELETE = 'PROJECT_DELETE',
  PROJECT_LIST_REPO = 'PROJECT_LIST_REPO',
  PROJECT_MODIFY_BINDINGS = 'PROJECT_MODIFY_BINDINGS',
  REPO_ADD_PIPELINE_READER = 'REPO_ADD_PIPELINE_READER',
  REPO_ADD_PIPELINE_WRITER = 'REPO_ADD_PIPELINE_WRITER',
  REPO_CREATE_BRANCH = 'REPO_CREATE_BRANCH',
  REPO_DELETE = 'REPO_DELETE',
  REPO_DELETE_BRANCH = 'REPO_DELETE_BRANCH',
  REPO_DELETE_COMMIT = 'REPO_DELETE_COMMIT',
  REPO_INSPECT_COMMIT = 'REPO_INSPECT_COMMIT',
  REPO_INSPECT_FILE = 'REPO_INSPECT_FILE',
  REPO_LIST_BRANCH = 'REPO_LIST_BRANCH',
  REPO_LIST_COMMIT = 'REPO_LIST_COMMIT',
  REPO_LIST_FILE = 'REPO_LIST_FILE',
  REPO_MODIFY_BINDINGS = 'REPO_MODIFY_BINDINGS',
  REPO_READ = 'REPO_READ',
  REPO_REMOVE_PIPELINE_READER = 'REPO_REMOVE_PIPELINE_READER',
  REPO_WRITE = 'REPO_WRITE',
  SECRET_DELETE = 'SECRET_DELETE',
  SECRET_INSPECT = 'SECRET_INSPECT',
}

export type EnterpriseInfo = {
  expiration: number;
  state: EnterpriseState;
};
